/**
 * Author(s): xuming.Wong <xuming.Wong@gmail.com>
 */

#include "M2MaterialLoader.h"

#include "OgreString.h"
#include "OgreStringConverter.h"
#include "OgreMesh.h"
#include "OgreMaterialManager.h"
#include "OgreTechnique.h"

#include "WOWArchive.h"
#include "WOWUtil.h"
#include "M2ModelInfo.h"
#include "M2TextureLoader.h"

namespace GNgine
{
	int M2MaterialLoader::_count=0;
	M2MaterialLoader::M2MaterialLoader(Ogre::String group,M2File* m2File)
		: _m2File(m2File),_group(group)
	{
		assert(_m2File);
		_count++;
	}

	Ogre::String M2MaterialLoader::loadBodyMaterial()
	{
		Ogre::String bodyMatName=_m2File->getFileName()+"/Material/BODY/"+Ogre::StringConverter::toString(_count);
		Ogre::String bodyTexName=_m2File->getFileName()+"/Texture/BODY/"+Ogre::StringConverter::toString(_count);
		
		if(Ogre::MaterialManager::getSingleton().resourceExists(bodyTexName)){
			Ogre::MaterialManager::getSingleton().unload(bodyTexName);
			Ogre::MaterialManager::getSingleton().remove(bodyTexName);
		}
		
		//load material into ogre
		Ogre::MaterialPtr bodyMat=Ogre::MaterialManager::getSingleton().create(bodyTexName,_group);

		bodyMat->getTechnique(0)->setCullingMode(Ogre::CULL_NONE);
		bodyMat->getTechnique(0)->setManualCullingMode(Ogre::MANUAL_CULL_NONE);
		bodyMat->getTechnique(0)->getPass(0)->setPolygonMode(Ogre::PM_SOLID);
		bodyMat->getTechnique(0)->getPass(0)->setCullingMode(Ogre::CULL_NONE);
		bodyMat->getTechnique(0)->getPass(0)->setDiffuse(Ogre::ColourValue(0.5,0.5,0.5));

		//when to delete loader?BUG: cause memory leak
		M2TextureLoader *loader=new M2TextureLoader(_m2File,M2_TEX_TYPE_CHAR_BODY);
		
		Ogre::TexturePtr tex= Ogre::TextureManager::getSingleton().create(bodyTexName, _group, true, loader);
		if (!tex.isNull()){
			Ogre::Pass* pass=bodyMat->getTechnique(0)->getPass(0);
			addTextureUnit(pass,bodyTexName);
		}

		return bodyTexName;
	}

	Ogre::String M2MaterialLoader::loadHairMaterial()
	{
		Ogre::String hairMatName=_m2File->getFileName()+"/Material/HAIR/"+Ogre::StringConverter::toString(_count);
		Ogre::String hairTexName=_m2File->getFileName()+"/Texture/HAIR/"+Ogre::StringConverter::toString(_count);
		
		if(Ogre::MaterialManager::getSingleton().resourceExists(hairTexName)){
			Ogre::MaterialManager::getSingleton().unload(hairTexName);
			Ogre::MaterialManager::getSingleton().remove(hairTexName);
		}
		
		//load material into ogre
		Ogre::MaterialPtr hairMat=Ogre::MaterialManager::getSingleton().create(hairTexName,_group);

		hairMat->getTechnique(0)->setCullingMode(Ogre::CULL_NONE);
		hairMat->getTechnique(0)->setManualCullingMode(Ogre::MANUAL_CULL_NONE);
		hairMat->getTechnique(0)->getPass(0)->setPolygonMode(Ogre::PM_SOLID);
		hairMat->getTechnique(0)->getPass(0)->setCullingMode(Ogre::CULL_NONE);
		hairMat->getTechnique(0)->getPass(0)->setDiffuse(Ogre::ColourValue(0.5,0.5,0.5));

		//when to delete loader?BUG: cause memory leak
		M2TextureLoader *loader=new M2TextureLoader(_m2File,M2_TEX_TYPE_CHAR_HAIR);
		
		Ogre::TexturePtr tex= Ogre::TextureManager::getSingleton().create(hairTexName, _group, true, loader);
		if (!tex.isNull()){
			Ogre::Pass* pass=hairMat->getTechnique(0)->getPass(0);
			addTextureUnit(pass,hairTexName);
		}

		return hairTexName;
	}


	Ogre::TextureUnitState* M2MaterialLoader::addTextureUnit(Ogre::Pass* pass,Ogre::String texName)
	{
		Ogre::TextureUnitState *state=pass->createTextureUnitState(texName);
		state->setTextureCoordSet(0);
		state->setTextureAddressingMode(Ogre::TextureUnitState::TAM_WRAP,Ogre::TextureUnitState::TAM_WRAP,Ogre::TextureUnitState::TAM_WRAP);
		return state;
	}
}
